Public Class ACDataGridViewDateTimePicker
   Inherits DateTimePicker
   Implements IDataGridViewEditingControl

   Private dataGridViewControl As DataGridView
   Private valueIsChanged As Boolean = False
   Private rowIndexNum As Integer

   Public Sub New()
      Me.Format = DateTimePickerFormat.Short
   End Sub

   Public Property EditingControlFormattedValue() As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue
      Get
         Return Me.Value.ToShortDateString()
      End Get
      Set(ByVal value As Object)
         If TypeOf value Is String Then
            Me.Value = DateTime.Parse(CStr(value))
         End If
      End Set
   End Property

   Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
      Return Me.Value.ToShortDateString()
   End Function

   Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
      Me.Font = dataGridViewCellStyle.Font
      Me.CalendarForeColor = dataGridViewCellStyle.ForeColor
      Me.CalendarMonthBackground = dataGridViewCellStyle.BackColor
   End Sub

   Public Property EditingControlRowIndex() As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex
      Get
         Return rowIndexNum
      End Get
      Set(ByVal value As Integer)
         rowIndexNum = value
      End Set
   End Property

   Public Function EditingControlWantsInputKey(ByVal key As Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey
      Select Case key And Keys.KeyCode
         Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp
            Return True

         Case Else
            Return False
      End Select
   End Function

   Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit

   End Sub

   Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange
      Get
         Return False
      End Get
   End Property

   Public Property EditingControlDataGridView() As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView
      Get
         Return dataGridViewControl
      End Get
      Set(ByVal value As DataGridView)
         dataGridViewControl = value
      End Set
   End Property

   Public Property EditingControlValueChanged() As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged
      Get
         Return valueIsChanged
      End Get
      Set(ByVal value As Boolean)
         valueIsChanged = value
      End Set
   End Property

   Public ReadOnly Property EditingControlCursor() As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor
      Get
         Return MyBase.Cursor
      End Get
   End Property

   Protected Overrides Sub OnValueChanged(ByVal eventargs As EventArgs)
      ' Notify the DataGridView that the contents of the cell have changed.
      valueIsChanged = True
      Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
      MyBase.OnValueChanged(eventargs)
   End Sub
End Class

Public Class ACDataGridViewDateTimePickerColumn
   Inherits DataGridViewColumn

   Public Sub New()
      MyBase.New(New ACDataGridViewDateTimePickerCell())
   End Sub

   Public Overrides Property CellTemplate() As DataGridViewCell
      Get
         Return MyBase.CellTemplate
      End Get
      Set(ByVal value As DataGridViewCell)
         If (value IsNot Nothing) AndAlso Not value.GetType().IsAssignableFrom(GetType(ACDataGridViewDateTimePickerCell)) Then
            Throw New InvalidCastException("Debe ser un ACDataGridViewDateTimePicker")
         End If
         MyBase.CellTemplate = value
      End Set
   End Property

End Class

Public Class ACDataGridViewDateTimePickerCell
   Inherits DataGridViewTextBoxCell

   Public Sub New()
      Me.Style.Format = "d"
   End Sub

   Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
      Try
         MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)

         Dim ctl As ACDataGridViewDateTimePicker = CType(DataGridView.EditingControl, ACDataGridViewDateTimePicker)

         If Me.Value Is DBNull.Value Then
            ctl.Value = DateTime.Today
         Else
            ctl.Value = CType(Me.Value, DateTime)
         End If
      Catch ex As Exception
      End Try
   End Sub

   Public Overrides ReadOnly Property EditType() As Type
      Get
         Return GetType(ACDataGridViewDateTimePicker)
      End Get
   End Property

   Public Overrides ReadOnly Property ValueType() As Type
      Get
         Return GetType(DateTime)
      End Get
   End Property

   Public Overrides ReadOnly Property DefaultNewRowValue() As Object
      Get
         Return DateTime.Now
      End Get
   End Property
End Class




